//再学链表
#include"SList.h"
//打印链表
void SLTPrint(SLTNode* phead)
{
    SLTNode* pcur = phead;
    while(pcur != NULL){
        printf("%d->",pcur->data);
        pcur = pcur->next;
    }
    printf("NULL\n");
}

//创建节点
SLTNode* SLTBuyNode(SLTDataType x)
{
    SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
    if(newnode == NULL){
        perror("malloc fail!");
        exit(1);
    }
    newnode->data = x;
    newnode->next = NULL;

    return newnode;
}

//尾插法
void SLTPushBack(SLTNode** pphead,SLTDataType x)
{   
    assert(*pphead);

    SLTNode* newnode = SLTBuynode(x);

    //若原链表为空
    if(*pphead == NULL){
        *pphead = newnode;
        return;
    }
    //原链表不为空 则需要找尾节点
    SLTNode* ptail = *pphead;
    while(ptail->next){
        ptail = ptail->next;
    }
    ptail->next = newnode;
}
//头插法
void SLTPushFront(SLTNode** pphead,SLTDataType x)
{
  assert(*pphead);

  SLTNode* newnode = SLTBuynode(x);  

  newnode->next = *pphead;
  *pphead = newnode;
}

//头删法
void SLTPopFront(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    //让第二个节点成为新的头 然后释放旧的头节点
    SLTNode* next = (*pphead)->next;
    free(*pphead);
    *pphead = next;
}
//尾删法
void SLTPopBack(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    //分为链表只有一个节点或多个节点考虑
    if((*pphead)->next == NULL){
        free(*pphead);
        *pphead = NULL;
        return;
    } 
    SLTNode* ptail = *pphead;
    SLTNode* prev = NULL;
    while(ptail->next){
        prev = ptail;
        ptail = ptail->next;
    }

    prev->next = NULL;
    free(ptail);
    ptail = NULL;
}

//查找
SLTNode* SLTFind(SLTNode** pphead,SLTDataType x)
{
    assert(pphead);

    SLTNode* pcur = *pphead;
    while(pcur){
        if(pcur->data == x){
            return pcur;
        }
        pcur = pcur->next;
    }

    //没有找到
    return NULL;
}

//指定位置前插入数据
void SLTInsert(SLTNode** pphead,SLTNode* pos,SLTDataType x)
{
    assert(pphead);
    assert(pos);
    assert(*pphead);

    SLTNode* newnode = SLTBuyNode(x);
    //pos刚好是头节点
    if(pos == *pphead){
        SLTPushFront(pphead,x);
        return;
    }

    //pos不是头节点
    SLTNode* prev = *pphead;
    while(prev->next != pos)
    {
        prev = prev->next;
    }
    prev->next = newnode;
    newnode->next = pos;
}
//指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos,SLTDataType x)
{
    assert(pos);

    SLTNode* newnode=SLTBuyNode(x);

    newnode->next = pos->next;
    pos->next = newnode;
}

//删除pos节点
void SLTErase(SLTNode** pphead,SLTNode* pos)
{
    assert(pphead);
    assert(pos);
    assert(*pphead);

    //若pos是头节点没有前驱节点 则执行头删
    if(*pphead == pos){
        SLTPopFront(pphead);
        return;
    }

    SLTNode* prev = *pphead;
    while(prev->next != pos){
        prev = prev->next;
    }
    prev->next = pos->next;
    free(pos);
    pos = NULL;
}
//删除pos后的节点
void SLTEraseAfter(SLTNode* pos)
{
    assert(pos);
    assert(pos->next);

    SLTNode* del = pos->next;
    pos->next = pos->next->next;
    free(del);
    del = NULL;
}

//销毁链表
void SListDestroy(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    SLTNode* pcur = *pphead;
    while(pcur){
        SLTNode* next = pcur->next;
        free(pcur);
        pcur = next;
    }
    *pphead = NULL;
}